package com.djz.stuinfomge.dao.impl;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.djz.stuinfomge.dao.BaseDao;
import com.djz.stuinfomge.entity.PageBean;
import com.djz.stuinfomge.exception.PageNumOutOfRange;
import com.djz.stuinfomge.util.Finder;


public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
    public BaseDaoImpl() {
	Type t = getClass().getGenericSuperclass();
	//instanceof判断，是为没有参数类型的子类服务的
	if(t instanceof ParameterizedType){
	    ParameterizedType pt = (ParameterizedType)t;
	    this.clazz = (Class<T>) pt.getActualTypeArguments()[0];
	}
	
    }

    protected long countQueryResult(Finder finder) {
	logger.debug("-------------rowCountQl: " + finder.getRowCountQl());
	Session session = getSession();
	Query query = session.createQuery(finder.getRowCountQl());
	finder.setParamsToQuery(query);
	return (Long) query.uniqueResult();
    }

    protected PageBean find(Finder finder, int pageNo, int size)
	    throws PageNumOutOfRange {
    	
	long totalCount = countQueryResult(finder);
	
	// 判断pageNo是否有效
	if ((pageNo - 1) * size + 1 > totalCount)
	    throw new PageNumOutOfRange();
	PageBean p = new PageBean(totalCount);
	
	Session session = getSession();
	Query query = session.createQuery(finder.getOrigQl());
	finder.setParamsToQuery(query);

	int f = (pageNo - 1) * size;
	if (f < 0)
	    f = 0;
	query.setFirstResult(f);
	query.setMaxResults(size);
	//logger.debug("--------------------here 2");
	List list = query.list();
	//logger.debug("--------------------here 3");
	p.setList(list);

	return p;
    }

    public void add(T t) {
	getHibernateTemplate().save(t);

    }

    public T get(int id) {
	return getHibernateTemplate().get(clazz, id);
    }

    public void remove(int id) {
	T t = getHibernateTemplate().get(clazz, id);
	getHibernateTemplate().delete(t);
    }

    public void update(T t) {
	getHibernateTemplate().merge(t);
    }

    @Autowired
    public void setTemplate(HibernateTemplate hibernateTemplate) {
	super.setHibernateTemplate(hibernateTemplate);
    }

    private Class<T> clazz;

}
